/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package controladores;

import controladores.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.TipoMaterial;
import entidades.Material;
import entidades.SubTipoMaterial;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author g
 */
public class SubTipoMaterialJpaController implements Serializable {

    public SubTipoMaterialJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(SubTipoMaterial subTipoMaterial) {
        if (subTipoMaterial.getLs_materiales() == null) {
            subTipoMaterial.setLs_materiales(new ArrayList<Material>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoMaterial tipoMaterial = subTipoMaterial.getTipoMaterial();
            if (tipoMaterial != null) {
                tipoMaterial = em.getReference(tipoMaterial.getClass(), tipoMaterial.getId());
                subTipoMaterial.setTipoMaterial(tipoMaterial);
            }
            List<Material> attachedLs_materiales = new ArrayList<Material>();
            for (Material ls_materialesMaterialToAttach : subTipoMaterial.getLs_materiales()) {
                ls_materialesMaterialToAttach = em.getReference(ls_materialesMaterialToAttach.getClass(), ls_materialesMaterialToAttach.getId());
                attachedLs_materiales.add(ls_materialesMaterialToAttach);
            }
            subTipoMaterial.setLs_materiales(attachedLs_materiales);
            em.persist(subTipoMaterial);
            if (tipoMaterial != null) {
                tipoMaterial.getLs_subtipos().add(subTipoMaterial);
                tipoMaterial = em.merge(tipoMaterial);
            }
            for (Material ls_materialesMaterial : subTipoMaterial.getLs_materiales()) {
                SubTipoMaterial oldSubTipoMaterialOfLs_materialesMaterial = ls_materialesMaterial.getSubTipoMaterial();
                ls_materialesMaterial.setSubTipoMaterial(subTipoMaterial);
                ls_materialesMaterial = em.merge(ls_materialesMaterial);
                if (oldSubTipoMaterialOfLs_materialesMaterial != null) {
                    oldSubTipoMaterialOfLs_materialesMaterial.getLs_materiales().remove(ls_materialesMaterial);
                    oldSubTipoMaterialOfLs_materialesMaterial = em.merge(oldSubTipoMaterialOfLs_materialesMaterial);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(SubTipoMaterial subTipoMaterial) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            SubTipoMaterial persistentSubTipoMaterial = em.find(SubTipoMaterial.class, subTipoMaterial.getId());
            TipoMaterial tipoMaterialOld = persistentSubTipoMaterial.getTipoMaterial();
            TipoMaterial tipoMaterialNew = subTipoMaterial.getTipoMaterial();
            List<Material> ls_materialesOld = persistentSubTipoMaterial.getLs_materiales();
            List<Material> ls_materialesNew = subTipoMaterial.getLs_materiales();
            if (tipoMaterialNew != null) {
                tipoMaterialNew = em.getReference(tipoMaterialNew.getClass(), tipoMaterialNew.getId());
                subTipoMaterial.setTipoMaterial(tipoMaterialNew);
            }
            List<Material> attachedLs_materialesNew = new ArrayList<Material>();
            for (Material ls_materialesNewMaterialToAttach : ls_materialesNew) {
                ls_materialesNewMaterialToAttach = em.getReference(ls_materialesNewMaterialToAttach.getClass(), ls_materialesNewMaterialToAttach.getId());
                attachedLs_materialesNew.add(ls_materialesNewMaterialToAttach);
            }
            ls_materialesNew = attachedLs_materialesNew;
            subTipoMaterial.setLs_materiales(ls_materialesNew);
            subTipoMaterial = em.merge(subTipoMaterial);
            if (tipoMaterialOld != null && !tipoMaterialOld.equals(tipoMaterialNew)) {
                tipoMaterialOld.getLs_subtipos().remove(subTipoMaterial);
                tipoMaterialOld = em.merge(tipoMaterialOld);
            }
            if (tipoMaterialNew != null && !tipoMaterialNew.equals(tipoMaterialOld)) {
                tipoMaterialNew.getLs_subtipos().add(subTipoMaterial);
                tipoMaterialNew = em.merge(tipoMaterialNew);
            }
            for (Material ls_materialesOldMaterial : ls_materialesOld) {
                if (!ls_materialesNew.contains(ls_materialesOldMaterial)) {
                    ls_materialesOldMaterial.setSubTipoMaterial(null);
                    ls_materialesOldMaterial = em.merge(ls_materialesOldMaterial);
                }
            }
            for (Material ls_materialesNewMaterial : ls_materialesNew) {
                if (!ls_materialesOld.contains(ls_materialesNewMaterial)) {
                    SubTipoMaterial oldSubTipoMaterialOfLs_materialesNewMaterial = ls_materialesNewMaterial.getSubTipoMaterial();
                    ls_materialesNewMaterial.setSubTipoMaterial(subTipoMaterial);
                    ls_materialesNewMaterial = em.merge(ls_materialesNewMaterial);
                    if (oldSubTipoMaterialOfLs_materialesNewMaterial != null && !oldSubTipoMaterialOfLs_materialesNewMaterial.equals(subTipoMaterial)) {
                        oldSubTipoMaterialOfLs_materialesNewMaterial.getLs_materiales().remove(ls_materialesNewMaterial);
                        oldSubTipoMaterialOfLs_materialesNewMaterial = em.merge(oldSubTipoMaterialOfLs_materialesNewMaterial);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = subTipoMaterial.getId();
                if (findSubTipoMaterial(id) == null) {
                    throw new NonexistentEntityException("The subTipoMaterial with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            SubTipoMaterial subTipoMaterial;
            try {
                subTipoMaterial = em.getReference(SubTipoMaterial.class, id);
                subTipoMaterial.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The subTipoMaterial with id " + id + " no longer exists.", enfe);
            }
            TipoMaterial tipoMaterial = subTipoMaterial.getTipoMaterial();
            if (tipoMaterial != null) {
                tipoMaterial.getLs_subtipos().remove(subTipoMaterial);
                tipoMaterial = em.merge(tipoMaterial);
            }
            List<Material> ls_materiales = subTipoMaterial.getLs_materiales();
            for (Material ls_materialesMaterial : ls_materiales) {
                ls_materialesMaterial.setSubTipoMaterial(null);
                ls_materialesMaterial = em.merge(ls_materialesMaterial);
            }
            em.remove(subTipoMaterial);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<SubTipoMaterial> findSubTipoMaterialEntities() {
        return findSubTipoMaterialEntities(true, -1, -1);
    }

    public List<SubTipoMaterial> findSubTipoMaterialEntities(int maxResults, int firstResult) {
        return findSubTipoMaterialEntities(false, maxResults, firstResult);
    }

    private List<SubTipoMaterial> findSubTipoMaterialEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(SubTipoMaterial.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public SubTipoMaterial findSubTipoMaterial(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(SubTipoMaterial.class, id);
        } finally {
            em.close();
        }
    }

    public int getSubTipoMaterialCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<SubTipoMaterial> rt = cq.from(SubTipoMaterial.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
